<!-- 操作追溯时间线组件 -->
<template>
  <div class="operation-timeline">
    <!-- 时间线控制面板 -->
    <div class="timeline-controls">
      <div class="control-left">
        <el-button-group size="small">
          <el-button @click="playTimeline" :disabled="isPlaying">
            <el-icon><VideoPlay /></el-icon>
            {{ isPlaying ? '播放中' : '播放' }}
          </el-button>
          <el-button @click="pauseTimeline" :disabled="!isPlaying">
            <el-icon><VideoPause /></el-icon>
            暂停
          </el-button>
          <el-button @click="resetTimeline">
            <el-icon><RefreshRight /></el-icon>
            重置
          </el-button>
        </el-button-group>

        <div class="playback-speed">
          <span class="speed-label">播放速度:</span>
          <el-select v-model="playbackSpeed" size="small" style="width: 80px">
            <el-option label="0.5x" :value="0.5" />
            <el-option label="1x" :value="1" />
            <el-option label="2x" :value="2" />
            <el-option label="5x" :value="5" />
          </el-select>
        </div>
      </div>

      <div class="control-right">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索操作..."
          size="small"
          clearable
          class="search-input"
          @input="handleSearch"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>
      </div>
    </div>

    <!-- 时间线进度条 -->
    <div class="timeline-progress" v-if="filteredTimelineData.length > 0">
      <div class="progress-info">
        <span class="current-time">{{ formatTime(currentPlayTime) }}</span>
        <span class="separator">-</span>
        <span class="total-time">{{ formatTime(totalDuration) }}</span>
      </div>
      <el-slider
        v-model="progressPercent"
        :max="100"
        :show-tooltip="false"
        @input="handleProgressChange"
        class="progress-slider"
      />
    </div>

    <!-- 时间线主体 -->
    <div class="timeline-body" v-loading="loading">
      <div v-if="filteredTimelineData.length === 0" class="empty-timeline">
        <el-empty description="暂无操作记录" />
      </div>
      
      <div v-else class="timeline-container">
        <el-timeline class="operation-timeline-list">
          <el-timeline-item
            v-for="(item, index) in paginatedData"
            :key="item.id"
            :timestamp="formatTimestamp(item.timestamp)"
            :type="getTimelineItemType(item)"
            :color="getTimelineItemColor(item)"
            :class="['timeline-item', { 
              active: currentPlayingIndex === index,
              highlighted: item.highlighted 
            }]"
          >
            <div class="timeline-content">
              <div class="operation-header">
                <div class="operation-info">
                  <el-icon class="operation-icon" :class="getOperationIconClass(item.type)">
                    <component :is="getOperationIcon(item.type)" />
                  </el-icon>
                  <span class="operation-type">{{ getOperationTypeLabel(item.type) }}</span>
                  <el-tag
                    :type="getResultTagType(item.result)"
                    size="small"
                    class="result-tag"
                  >
                    {{ item.result === 'success' ? '成功' : '失败' }}
                  </el-tag>
                </div>
                
                <div class="operation-meta">
                  <span class="user-info">
                    <el-icon><User /></el-icon>
                    {{ item.user }}
                  </span>
                  <span v-if="item.ip" class="ip-info">
                    <el-icon><Position /></el-icon>
                    {{ item.ip }}
                  </span>
                </div>
              </div>

              <div class="operation-description">
                {{ item.description }}
              </div>

              <div v-if="item.details || item.changes" class="operation-details">
                <div v-if="item.details" class="detail-item">
                  <span class="detail-label">详情:</span>
                  <span class="detail-value">{{ item.details }}</span>
                </div>
                <div v-if="item.changes" class="detail-item">
                  <span class="detail-label">变更:</span>
                  <div class="changes-list">
                    <el-tag
                      v-for="change in item.changes"
                      :key="change"
                      size="small"
                      type="info"
                      class="change-tag"
                    >
                      {{ change }}
                    </el-tag>
                  </div>
                </div>
              </div>

              <div class="operation-actions">
                <el-button size="small" text @click="replayOperation(item)">
                  <el-icon><VideoPlay /></el-icon>
                  回放
                </el-button>
                <el-button size="small" text @click="viewOperationDetails(item)">
                  <el-icon><View /></el-icon>
                  详细
                </el-button>
                <el-button size="small" text @click="exportSingleLog(item)">
                  <el-icon><Download /></el-icon>
                  导出
                </el-button>
              </div>
            </div>
          </el-timeline-item>
        </el-timeline>
      </div>
    </div>

    <!-- 分页控制 -->
    <div class="timeline-footer" v-if="filteredTimelineData.length > 0">
      <div class="footer-left">
        <span class="timeline-stats">
          共 {{ filteredTimelineData.length }} 条记录
          <span v-if="searchKeyword">（搜索结果）</span>
        </span>
      </div>
      
      <div class="footer-right">
        <el-pagination
          v-model:current-page="currentPage"
          :page-size="pageSize"
          :total="filteredTimelineData.length"
          layout="prev, pager, next, sizes"
          :page-sizes="[10, 20, 50, 100]"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          size="small"
        />
      </div>
    </div>

    <!-- 操作详情弹窗 -->
    <el-dialog
      v-model="detailDialogVisible"
      title="操作详情"
      width="60vw"
      :before-close="handleDetailDialogClose"
    >
      <div class="operation-detail-content" v-if="selectedOperation">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="操作类型">
            <el-tag :type="getResultTagType(selectedOperation.result)">
              {{ getOperationTypeLabel(selectedOperation.type) }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="操作用户">
            {{ selectedOperation.user }}
          </el-descriptions-item>
          <el-descriptions-item label="操作时间">
            {{ formatTimestamp(selectedOperation.timestamp) }}
          </el-descriptions-item>
          <el-descriptions-item label="执行结果">
            <el-tag :type="getResultTagType(selectedOperation.result)">
              {{ selectedOperation.result === 'success' ? '成功' : '失败' }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="IP地址" v-if="selectedOperation.ip">
            {{ selectedOperation.ip }}
          </el-descriptions-item>
          <el-descriptions-item label="操作描述" :span="2">
            {{ selectedOperation.description }}
          </el-descriptions-item>
          <el-descriptions-item label="详细信息" :span="2" v-if="selectedOperation.details">
            {{ selectedOperation.details }}
          </el-descriptions-item>
          <el-descriptions-item label="变更内容" :span="2" v-if="selectedOperation.changes">
            <div class="changes-detail">
              <el-tag
                v-for="change in selectedOperation.changes"
                :key="change"
                size="small"
                type="info"
                class="change-detail-tag"
              >
                {{ change }}
              </el-tag>
            </div>
          </el-descriptions-item>
        </el-descriptions>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="detailDialogVisible = false">关闭</el-button>
          <el-button type="primary" @click="exportSingleLog(selectedOperation)">
            <el-icon><Download /></el-icon>
            导出此记录
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
import {
  VideoPlay,
  VideoPause,
  RefreshRight,
  Search,
  User,
  Position,
  View,
  Download,
  DataLine,
  Setting,
  UserFilled,
  Key,
  Warning,
  Check
} from '@element-plus/icons-vue'

// Props
const props = defineProps({
  timelineData: {
    type: Array,
    default: () => []
  },
  loading: {
    type: Boolean,
    default: false
  }
})

// Emits
const emit = defineEmits(['playback', 'exportLog'])

// 响应式数据
const isPlaying = ref(false)
const playbackSpeed = ref(1)
const currentPlayTime = ref(0)
const currentPlayingIndex = ref(-1)
const progressPercent = ref(0)
const searchKeyword = ref('')
const currentPage = ref(1)
const pageSize = ref(20)
const detailDialogVisible = ref(false)
const selectedOperation = ref(null)

// 播放控制
let playbackTimer = null

// 计算属性
const filteredTimelineData = computed(() => {
  let filtered = props.timelineData

  if (searchKeyword.value) {
    const keyword = searchKeyword.value.toLowerCase()
    filtered = filtered.filter(item => 
      item.description.toLowerCase().includes(keyword) ||
      item.user.toLowerCase().includes(keyword) ||
      getOperationTypeLabel(item.type).toLowerCase().includes(keyword)
    )
  }

  // 按时间排序
  return filtered.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
})

const paginatedData = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return filteredTimelineData.value.slice(start, end)
})

const totalDuration = computed(() => {
  if (filteredTimelineData.value.length === 0) return 0
  const earliest = Math.min(...filteredTimelineData.value.map(item => new Date(item.timestamp).getTime()))
  const latest = Math.max(...filteredTimelineData.value.map(item => new Date(item.timestamp).getTime()))
  return latest - earliest
})

// 播放控制方法
const playTimeline = () => {
  if (filteredTimelineData.value.length === 0) {
    ElMessage.warning('暂无数据可播放')
    return
  }

  isPlaying.value = true
  playbackTimer = setInterval(() => {
    if (currentPlayingIndex.value < filteredTimelineData.value.length - 1) {
      currentPlayingIndex.value++
      updatePlayProgress()
      
      // 高亮当前播放的操作
      filteredTimelineData.value.forEach((item, index) => {
        item.highlighted = index === currentPlayingIndex.value
      })
      
      // 触发回放事件
      emit('playback', filteredTimelineData.value[currentPlayingIndex.value])
    } else {
      pauseTimeline()
      ElMessage.success('时间线播放完成')
    }
  }, 1000 / playbackSpeed.value)
}

const pauseTimeline = () => {
  isPlaying.value = false
  if (playbackTimer) {
    clearInterval(playbackTimer)
    playbackTimer = null
  }
}

const resetTimeline = () => {
  pauseTimeline()
  currentPlayingIndex.value = -1
  currentPlayTime.value = 0
  progressPercent.value = 0
  
  // 清除高亮
  filteredTimelineData.value.forEach(item => {
    item.highlighted = false
  })
}

const updatePlayProgress = () => {
  if (filteredTimelineData.value.length > 0) {
    progressPercent.value = ((currentPlayingIndex.value + 1) / filteredTimelineData.value.length) * 100
    
    if (currentPlayingIndex.value >= 0) {
      currentPlayTime.value = new Date(filteredTimelineData.value[currentPlayingIndex.value].timestamp).getTime()
    }
  }
}

const handleProgressChange = (value) => {
  pauseTimeline()
  const targetIndex = Math.floor((value / 100) * filteredTimelineData.value.length)
  currentPlayingIndex.value = Math.max(0, targetIndex - 1)
  updatePlayProgress()
}

// 搜索处理
const handleSearch = () => {
  currentPage.value = 1
  resetTimeline()
}

// 分页处理
const handleSizeChange = (newSize) => {
  pageSize.value = newSize
  currentPage.value = 1
}

const handleCurrentChange = (newPage) => {
  currentPage.value = newPage
}

// 操作类型相关
const getOperationTypeLabel = (type) => {
  const labelMap = {
    user_login: '用户登录',
    data_access: '数据访问',
    permission_change: '权限变更',
    system_config: '系统配置'
  }
  return labelMap[type] || type
}

const getOperationIcon = (type) => {
  const iconMap = {
    user_login: UserFilled,
    data_access: DataLine,
    permission_change: Key,
    system_config: Setting
  }
  return iconMap[type] || Setting
}

const getOperationIconClass = (type) => {
  return `operation-icon-${type}`
}

const getTimelineItemType = (item) => {
  return item.result === 'success' ? 'success' : 'danger'
}

const getTimelineItemColor = (item) => {
  const colorMap = {
    user_login: '#409EFF',
    data_access: '#67C23A',
    permission_change: '#E6A23C',
    system_config: '#F56C6C'
  }
  return item.result === 'success' ? colorMap[item.type] : '#F56C6C'
}

const getResultTagType = (result) => {
  return result === 'success' ? 'success' : 'danger'
}

// 操作处理
const replayOperation = (operation) => {
  emit('playback', operation)
  ElMessage.info(`正在回放操作: ${operation.description}`)
}

const viewOperationDetails = (operation) => {
  selectedOperation.value = operation
  detailDialogVisible.value = true
}

const exportSingleLog = (operation) => {
  emit('exportLog', operation)
}

const handleDetailDialogClose = (done) => {
  done()
}

// 工具函数
const formatTime = (timestamp) => {
  if (!timestamp) return '--'
  return new Date(timestamp).toLocaleString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

const formatTimestamp = (timestamp) => {
  return new Date(timestamp).toLocaleString('zh-CN')
}

// 监听播放速度变化
watch(playbackSpeed, (newSpeed) => {
  if (isPlaying.value) {
    pauseTimeline()
    playTimeline()
  }
})

// 生命周期
onBeforeUnmount(() => {
  pauseTimeline()
})

onMounted(() => {
  // 初始化
})
</script>

<style scoped>
.operation-timeline {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 1.5vh;
}

/* 时间线控制面板 */
.timeline-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1vh 1.5vw;
  background: #1f2d3d;
  border: 1px solid #2d3a4b;
  border-radius: 0.5vh;
}

.control-left {
  display: flex;
  align-items: center;
  gap: 2vw;
}

.playback-speed {
  display: flex;
  align-items: center;
  gap: 0.5vw;
}

.speed-label {
  font-size: 0.8rem;
  color: #bfcbd9;
}

.control-right {
  display: flex;
  align-items: center;
}

.search-input {
  width: 15vw;
  min-width: 200px;
}

/* 时间线进度条 */
.timeline-progress {
  padding: 0 1.5vw;
}

.progress-info {
  display: flex;
  justify-content: space-between;
  margin-bottom: 0.5vh;
  font-size: 0.75rem;
  color: #8591a3;
}

.separator {
  margin: 0 0.5vw;
}

.progress-slider {
  margin: 0;
}

/* 时间线主体 */
.timeline-body {
  flex: 1;
  overflow-y: auto;
  padding: 0 1.5vw;
}

.empty-timeline {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.timeline-container {
  height: 100%;
}

.operation-timeline-list {
  padding: 1vh 0;
}

.timeline-item {
  margin-bottom: 2vh;
  transition: all 0.3s ease;
}

.timeline-item.active {
  background: rgba(64, 158, 255, 0.1);
  border-radius: 0.5vh;
  padding: 1vh;
  margin: 0 -1vh 2vh -1vh;
}

.timeline-item.highlighted {
  background: rgba(230, 162, 60, 0.15);
  border-radius: 0.5vh;
  padding: 1vh;
  margin: 0 -1vh 2vh -1vh;
}

/* 时间线内容 */
.timeline-content {
  background: #263445;
  border: 1px solid #2d3a4b;
  border-radius: 0.8vh;
  padding: 1.5vh;
  box-shadow: 0 0.2vh 0.8vh rgba(0, 0, 0, 0.1);
}

.operation-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1vh;
}

.operation-info {
  display: flex;
  align-items: center;
  gap: 1vw;
}

.operation-icon {
  font-size: 1.2rem;
}

.operation-icon-user_login {
  color: #409EFF;
}

.operation-icon-data_access {
  color: #67C23A;
}

.operation-icon-permission_change {
  color: #E6A23C;
}

.operation-icon-system_config {
  color: #F56C6C;
}

.operation-type {
  font-weight: 600;
  color: #bfcbd9;
}

.result-tag {
  font-weight: 600;
}

.operation-meta {
  display: flex;
  align-items: center;
  gap: 1.5vw;
  font-size: 0.8rem;
  color: #8591a3;
}

.user-info, .ip-info {
  display: flex;
  align-items: center;
  gap: 0.3vw;
}

.operation-description {
  margin-bottom: 1vh;
  color: #bfcbd9;
  line-height: 1.5;
}

.operation-details {
  margin-bottom: 1vh;
  padding: 1vh;
  background: #1f2d3d;
  border-radius: 0.5vh;
  border: 1px solid #2d3a4b;
}

.detail-item {
  display: flex;
  align-items: flex-start;
  gap: 1vw;
  margin-bottom: 0.5vh;
}

.detail-item:last-child {
  margin-bottom: 0;
}

.detail-label {
  font-weight: 600;
  color: #8591a3;
  min-width: 3vw;
}

.detail-value {
  color: #bfcbd9;
}

.changes-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5vw;
}

.change-tag {
  margin: 0;
}

.operation-actions {
  display: flex;
  gap: 1vw;
  justify-content: flex-end;
}

/* 时间线底部 */
.timeline-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1vh 1.5vw;
  background: #1f2d3d;
  border: 1px solid #2d3a4b;
  border-radius: 0.5vh;
}

.timeline-stats {
  font-size: 0.8rem;
  color: #8591a3;
}

/* 操作详情弹窗 */
.operation-detail-content {
  padding: 1vh;
}

.changes-detail {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5vw;
}

.change-detail-tag {
  margin: 0;
}

/* 滚动条样式 */
.timeline-body::-webkit-scrollbar {
  width: 8px;
}

.timeline-body::-webkit-scrollbar-track {
  background: #1f2d3d;
  border-radius: 4px;
}

.timeline-body::-webkit-scrollbar-thumb {
  background: #2d3a4b;
  border-radius: 4px;
  transition: background 0.3s ease;
}

.timeline-body::-webkit-scrollbar-thumb:hover {
  background: #409EFF;
}

/* Element Plus 组件深色主题覆盖 */
.operation-timeline :deep(.el-timeline-item__timestamp) {
  color: #8591a3 !important;
  font-size: 0.75rem !important;
}

.operation-timeline :deep(.el-timeline-item__node) {
  border-color: #2d3a4b !important;
}

.operation-timeline :deep(.el-timeline-item__tail) {
  border-left-color: #2d3a4b !important;
}

.operation-timeline :deep(.el-empty__description) {
  color: #8591a3 !important;
}

.operation-timeline :deep(.el-slider__runway) {
  background: #2d3a4b !important;
}

.operation-timeline :deep(.el-slider__bar) {
  background: #409EFF !important;
}

.operation-timeline :deep(.el-slider__button) {
  background: #409EFF !important;
  border-color: #409EFF !important;
}

.operation-timeline :deep(.el-pagination) {
  color: #bfcbd9 !important;
}

.operation-timeline :deep(.el-pagination .el-pager li) {
  background: #263445 !important;
  color: #bfcbd9 !important;
  border: 1px solid #2d3a4b !important;
}

.operation-timeline :deep(.el-pagination .el-pager li:hover) {
  color: #409EFF !important;
}

.operation-timeline :deep(.el-pagination .el-pager li.active) {
  background: #409EFF !important;
  color: #ffffff !important;
}

.operation-timeline :deep(.el-pagination button) {
  background: #263445 !important;
  color: #bfcbd9 !important;
  border-color: #2d3a4b !important;
}

.operation-timeline :deep(.el-pagination button:hover) {
  color: #409EFF !important;
}

.operation-timeline :deep(.el-select .el-input__wrapper) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.operation-timeline :deep(.el-descriptions) {
  background: transparent !important;
}

.operation-timeline :deep(.el-descriptions__header) {
  background: #1f2d3d !important;
  color: #bfcbd9 !important;
}

.operation-timeline :deep(.el-descriptions__body) {
  background: #263445 !important;
}

.operation-timeline :deep(.el-descriptions-item__label) {
  background: #1f2d3d !important;
  color: #bfcbd9 !important;
}

.operation-timeline :deep(.el-descriptions-item__content) {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .timeline-controls {
    flex-direction: column;
    gap: 1vh;
  }
  
  .control-left, .control-right {
    width: 100%;
    justify-content: center;
  }
  
  .search-input {
    width: 100%;
    min-width: auto;
  }
  
  .operation-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 1vh;
  }
  
  .operation-meta {
    width: 100%;
    justify-content: flex-start;
  }
}

@media (max-width: 768px) {
  .timeline-footer {
    flex-direction: column;
    gap: 1vh;
  }
  
  .operation-actions {
    flex-wrap: wrap;
    justify-content: center;
  }
  
  .changes-list {
    justify-content: flex-start;
  }
}
</style>